/*
 * Copyright (c) 2007 Thomas Fors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// =======================================================
// Display Routines
// =======================================================


// -------------------------------------------------------
// Display()
// Constructor
// -------------------------------------------------------
function Display() {
	
	this.files = new Array();			// array of debug output files
	
	this.docName = activeDocument.name;	// save document name so it can be selected later
	try {
		this.statusWnd = documents.getByName("ACR Calibrator Status Window");
	} catch (e) {
		// Doesn't exist
	}
	
	this.status = "";
	this.statusSpace = "";
	
	this.startTime = new Date();
	
	this.linesOfBlackText = 0;
	this.linesOfRedText = 0;
	this.linesOfGrayText = 0;
	
	this.refreshBlackText = false;
	this.refreshRedText = false;
	this.refreshGrayText = false;
	this.refreshResultsText = false;
	
	this.blackText = "";
	this.settingsText = "";
	this.redText = "";
	this.grayText = "";
	this.resultsText = "";
	
	// Mark all the settings with invalid data
	this.temp = Number.POSITIVE_INFINITY;
	this.tint = Number.POSITIVE_INFINITY;
	this.exps = Number.POSITIVE_INFINITY;
	this.shad = Number.POSITIVE_INFINITY;
	this.brgh = Number.POSITIVE_INFINITY;
	this.cntr = Number.POSITIVE_INFINITY;
	this.strt = Number.POSITIVE_INFINITY;
	this.blkb = Number.POSITIVE_INFINITY;
	this.rhue = Number.POSITIVE_INFINITY;
	this.rsat = Number.POSITIVE_INFINITY;
	this.ghue = Number.POSITIVE_INFINITY;
	this.gsat = Number.POSITIVE_INFINITY;
	this.bhue = Number.POSITIVE_INFINITY;
	this.bsat = Number.POSITIVE_INFINITY;
	
	this.NewStatusWindow();
}

// -------------------------------------------------------
// GetActiveDocPath()
// -------------------------------------------------------
Display.prototype['GetActiveDocPath'] = function () {
	return activeDocument.path.absoluteURI;
}

// -------------------------------------------------------
// GetActiveDocFullName()
// -------------------------------------------------------
Display.prototype['GetActiveDocFullName'] = function () {
	return activeDocument.fullName.absoluteURI;
}

// -------------------------------------------------------
// GetElapsedMinutes()
// -------------------------------------------------------
Display.prototype['GetElapsedMinutes'] = function () {
	var now = new Date();
	
	return Math.round( ((now - this.startTime) / 1000 / 60) * 100) / 100;
}

// -------------------------------------------------------
// SelectRawWnd()
// -------------------------------------------------------
Display.prototype['SelectRawWnd'] = function () {
	// Select raw file window
	try {
		activeDocument = documents.getByName(this.docName);
	} catch (e) {
		// Doesn't exist
	}
}

// -------------------------------------------------------
// SelectStatusWnd()
// -------------------------------------------------------
Display.prototype['SelectStatusWnd'] = function () {
	try {
		activeDocument = documents.getByName("ACR Calibrator Status Window");
	} catch (e) {
		// Doesn't exist
	}
}

// -------------------------------------------------------
// PurgeHistory()
// -------------------------------------------------------
Display.prototype['PurgeHistory'] = function () {
	var desc1 = new ActionDescriptor();
	desc1.putEnumerated( charIDToTypeID( "null" ), charIDToTypeID( "PrgI" ), charIDToTypeID( "Hsty" ) );
	executeAction( charIDToTypeID( "Prge" ), desc1, DialogModes.NO );
}

// -------------------------------------------------------
// UpdateSettingsText()
// -------------------------------------------------------
Display.prototype['UpdateSettingsText'] = function () {
	this.settingsText = "";
	
	if (this.temp != Number.POSITIVE_INFINITY)
		this.settingsText += "Color Temp: " + this.temp + "\r";
	if (this.tint != Number.POSITIVE_INFINITY)
		this.settingsText += "Tint: " + this.tint + "\r";
	if (this.exps != Number.POSITIVE_INFINITY)
		this.settingsText += "Exposure: " + this.exps + "\r";
	if (this.shad != Number.POSITIVE_INFINITY)
		this.settingsText += "Shadows: " + this.shad + "\r";
	if (this.brgh != Number.POSITIVE_INFINITY)
		this.settingsText += "Brightness: " + this.brgh + "\r";
	if (this.cntr != Number.POSITIVE_INFINITY)
		this.settingsText += "Contrast: " + this.cntr + "\r";
	if (this.strt != Number.POSITIVE_INFINITY)
		this.settingsText += "Saturation: " + this.strt + "\r";
	if (this.blkb != Number.POSITIVE_INFINITY)
		this.settingsText += "Shadow Tint: " + this.blkb + "\r";
	if (this.rhue != Number.POSITIVE_INFINITY)
		this.settingsText += "Red Hue: " + this.rhue + "\r";
	if (this.rsat != Number.POSITIVE_INFINITY)
		this.settingsText += "Red Sat: " + this.rsat + "\r";
	if (this.ghue != Number.POSITIVE_INFINITY)
		this.settingsText += "Green Hue: " + this.ghue + "\r";
	if (this.gsat != Number.POSITIVE_INFINITY)
		this.settingsText += "Green Sat: " + this.gsat + "\r";
	if (this.bhue != Number.POSITIVE_INFINITY)
		this.settingsText += "Blue Hue: " + this.bhue + "\r";
	if (this.bsat != Number.POSITIVE_INFINITY)
		this.settingsText += "Blue Sat: " + this.bsat + "\r";
}

// -------------------------------------------------------
// PostResults()
// -------------------------------------------------------
Display.prototype['PostResults'] = function (msg, bPass, score) {
	this.resultsText += msg + " " +  + Math.round(score*10000)/10000 + "\r";
	this.refreshResultsText = true;
	this.Refresh();
}


// -------------------------------------------------------
// Refresh()
// -------------------------------------------------------
Display.prototype['Refresh'] = function () {
	var i, space;
	var nTries = 0;
	var bSuccessful = false;
	
	while ( !bSuccessful && nTries < 3 ) {
		try {
			
			this.SelectStatusWnd();
			
			this.UpdateSettingsText();
			
			// count the lines
			this.linesOfBlackText = this.CountLines(this.blackText);
			this.linesOfBlackText += this.CountLines(this.settingsText);
			if ( this.refreshRedText ) {
				this.linesOfRedText = this.CountLines(this.redText);
			}
			if ( this.refreshGrayText ) {
				this.linesOfGrayText = this.CountLines(this.grayText);
			}
			
			// Display the text
			space = "";
			for ( i=0; i<(this.linesOfBlackText+this.linesOfRedText); i++ ) {
				space += "\r";
			}
			this.grayTextLayer.textItem.contents = space + this.grayText;
			space = "";
			for ( i=0; i<this.linesOfBlackText; i++ ) {
				space += "\r";
			}
			this.redTextLayer.textItem.contents = space + this.redText;
			this.blackTextLayer.textItem.contents = this.blackText + this.settingsText;
			
			if ( this.refreshResultsText )
				this.resultsTextLayer.textItem.contents = "\r\r\r\r\r\r" + this.resultsText;
			
			this.refreshBlackText = false;
			this.refreshRedText = false;
			this.refreshGrayText = false;
			this.refreshResultsText = false;
			
			this.WaitForRedraw();
			
			this.SelectRawWnd();
			
			bSuccessful = true;
		} catch (e) {
			// Status window not selected for some reason
			nTries++;
		}
	}
	
	if ( nTries >= 3 ) {
		throw ("Error writing to status window.  Script aborted.");
	}
	
	this.PurgeHistory();
}

// -------------------------------------------------------
// WaitForRedraw()
// -------------------------------------------------------
Display.prototype['WaitForRedraw'] = function () {
	var eventWait = charIDToTypeID('Wait');
	var enumRedrawComplete = charIDToTypeID('RdCm');
	var typeState = charIDToTypeID('Stte');
	var keyState = charIDToTypeID('Stte');
	var desc = new ActionDescriptor();
	desc.putEnumerated(keyState, typeState, enumRedrawComplete);
	executeAction(eventWait, desc, DialogModes.NO);
}

// -------------------------------------------------------
// CountLines()
// -------------------------------------------------------
Display.prototype['CountLines'] = function (data) {
	var lines = data.split("\r");
	return lines.length - 1;
}


// -------------------------------------------------------
// NewStatusWindow()
// -------------------------------------------------------
Display.prototype['NewStatusWindow'] = function () {
	var statusWnd, bOldWndExists = true;
	try {
		statusWnd = documents.getByName("ACR Calibrator Status Window");
	} catch (e) {
		bOldWndExists = false;
	}
	if ( bOldWndExists ) {
		statusWnd.close(SaveOptions.DONOTSAVECHANGES);
	}
	
	// Create new document
    var desc1 = new ActionDescriptor();
	var desc2 = new ActionDescriptor();
	desc2.putString( charIDToTypeID( "Nm  " ), "ACR Calibrator Status Window" );
	desc2.putClass( charIDToTypeID( "Md  " ), charIDToTypeID( "RGBM" ) );
	desc2.putUnitDouble( charIDToTypeID( "Wdth" ), charIDToTypeID( "#Rlt" ), 640.000000 );
	desc2.putUnitDouble( charIDToTypeID( "Hght" ), charIDToTypeID( "#Rlt" ), 480.000000 );
	desc2.putUnitDouble( charIDToTypeID( "Rslt" ), charIDToTypeID( "#Rsl" ), 72.000000 );
	desc2.putDouble( stringIDToTypeID( "pixelScaleFactor" ), 1.000000 );
	desc2.putEnumerated( charIDToTypeID( "Fl  " ), charIDToTypeID( "Fl  " ), charIDToTypeID( "Wht " ) );
	desc2.putInteger( charIDToTypeID( "Dpth" ), 8 );
	desc2.putString( stringIDToTypeID( "profile" ), "ProPhoto RGB" );
    desc1.putObject( charIDToTypeID( "Nw  " ), charIDToTypeID( "Dcmn" ), desc2 );
	
	executeAction(charIDToTypeID("Mk  "), desc1, DialogModes.NO);
	
	this.statusWnd = documents.getByName("ACR Calibrator Status Window");
	
	// Select Status Window
	activeDocument = this.statusWnd;
	
	// Create the text layers
	var color = new SolidColor();
	color.rgb = new RGBColor();
	this.blackTextLayer = activeDocument.artLayers.add();
	this.blackTextLayer.kind = LayerKind.TEXT;
	this.blackTextLayer.name = "blackText";
	this.blackTextLayer.textItem.position = Array(activeDocument.width*0.005, activeDocument.height*0.03);
	this.blackTextLayer.textItem.size = 14;
	this.blackTextLayer.textItem.font = "Verdana";
	color.rgb.red = 0;
	color.rgb.green = 0;
	color.rgb.blue = 0;
	this.blackTextLayer.textItem.color = color;
	
	this.redTextLayer = activeDocument.artLayers.add();
	this.redTextLayer.kind = LayerKind.TEXT;
	this.redTextLayer.name = "redText";
	this.redTextLayer.textItem.position = Array(activeDocument.width*0.005, activeDocument.height*0.03);
	this.redTextLayer.textItem.size = 14;
	this.redTextLayer.textItem.font = "Verdana";
	color.rgb.red = 255;
	color.rgb.green = 0;
	color.rgb.blue = 0;
	this.redTextLayer.textItem.color = color;
	
	this.grayTextLayer = activeDocument.artLayers.add();
	this.grayTextLayer.kind = LayerKind.TEXT;
	this.grayTextLayer.name = "grayText";
	this.grayTextLayer.textItem.position = Array(activeDocument.width*0.005, activeDocument.height*0.03);
	this.grayTextLayer.textItem.size = 14;
	this.grayTextLayer.textItem.font = "Verdana";
	color.rgb.red = 128;
	color.rgb.green = 128;
	color.rgb.blue = 128;
	this.grayTextLayer.textItem.color = color;
	
	this.resultsTextLayer = activeDocument.artLayers.add();
	this.resultsTextLayer.kind = LayerKind.TEXT;
	this.resultsTextLayer.name = "resultsText";
	this.resultsTextLayer.textItem.position = Array(activeDocument.width*0.605, activeDocument.height*0.03);
	this.resultsTextLayer.textItem.size = 14;
	this.resultsTextLayer.textItem.font = "Verdana";
	color.rgb.red = 0;
	color.rgb.green = 0;
	color.rgb.blue = 0;
	this.resultsTextLayer.textItem.color = color;
	
	this.SelectRawWnd();
}


// -------------------------------------------------------
// DisplayStatus()
// -------------------------------------------------------
Display.prototype['DisplayStatus'] = function (data) {
	var lines = data.split("\r");
	
	if ( data.length > 0 ) {
		this.redText = lines[0] + "\r";
		this.refreshRedText = true;
	}
	
	this.grayText = "";
	for ( i=1; i<lines.length; i++ ) {
		this.grayText += lines[i] + "\r";
	}
	
	if ( data.length > 0 && lines[0] != "Done.") {
		this.grayText += "  Elapsed Time: " + this.GetElapsedMinutes() + " mins.  Speed: " + Math.round(acr.nOpens/this.GetElapsedMinutes()*100)/100;
	}
	this.refreshGrayText = true;
	
	this.Refresh();
}

// -------------------------------------------------------
// AddStatusLine()
// -------------------------------------------------------
Display.prototype['AddStatusLine'] = function (status) {
	this.blackText += status + "\r";
	this.refreshBlackText = true;
}
